package framework.storage;

import framework.utils.Base32Util;
import framework.utils.Base58Util;
import framework.utils.IdUtil;
import framework.utils.UUIDUtil;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;

import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class FilePathBuilder {

    private Long identity;
    private UUID uuid;
    private ZonedDateTime time;
    private String ext;
    private final List<String> list = new ArrayList<>();
    @Getter
    @Setter
    private ZoneId zoneId = ZoneOffset.UTC;

    public FilePathBuilder() {

    }

    public String build() {
        return "/" + String.join("/", list) + (StringUtils.isBlank(ext) ? "" : ext);
    }

    protected UUID getUUID() {
        if (uuid == null) {
            uuid = UUID.randomUUID();
        }
        return uuid;
    }

    protected Long getIdentity() {
        if (identity == null) {
            identity = IdUtil.newId();
        }
        return identity;
    }

    protected Long getIdentity(Long id) {
        identity = id;
        return identity;
    }

    protected ZonedDateTime getTime() {
        if (time == null) {
            time = ZonedDateTime.now(getZoneId());
        }
        return time;
    }

    public FilePathBuilder append(String fragment) {
        list.add(fragment);
        return this;
    }

    public FilePathBuilder uuid() {
        list.add(getUUID().toString().replace("-", ""));
        return this;
    }

    public FilePathBuilder base32() {
        list.add(Base32Util.encode(getIdentity()));
        return this;
    }

    public FilePathBuilder base58() {
        list.add(Base58Util.encodeBytes(UUIDUtil.toBytes(getUUID())));
        return this;
    }

    public FilePathBuilder id() {
        list.add("" + getIdentity());
        return this;
    }

    public FilePathBuilder id(Long id) {
        list.add("" + getIdentity());
        return this;
    }

    public FilePathBuilder partId() {
        long c = getIdentity();
        long a = c % 99;
        long b = c % 9999;
        list.add("" + a);
        list.add("" + b);
        return this;
    }

    public FilePathBuilder partTime() {
        long c = getTime().toEpochSecond();
        long a = c % 99;
        long b = c % 9999;
        list.add("" + a);
        list.add("" + b);
        return this;
    }

    public FilePathBuilder year() {
        list.add("" + getTime().getYear());
        return this;
    }

    public FilePathBuilder month() {
        int v = getTime().getMonthValue();
        if (v < 10) {
            list.add("0" + v);
        } else {
            list.add("" + v);
        }
        return this;
    }

    public FilePathBuilder day() {
        int v = getTime().getDayOfMonth();
        if (v < 10) {
            list.add("0" + v);
        } else {
            list.add("" + v);
        }
        return this;
    }

    public FilePathBuilder extension(String ext) {
        if (StringUtils.isNotBlank(ext)) {
            this.ext = "." + ext;
        } else {
            this.ext = "";
        }
        return this;
    }

    /**
     * /2025/05/145252423423432.ext
     *
     * @param ext
     * @return
     */
    public static String buildYearMonthIDFilePath(String ext) {
        return new FilePathBuilder().year().month().id().extension(ext).build();
    }

    /**
     * /2025/05/abcd.....3e.ext
     *
     * @return
     */
    public static String buildYearMonthUUIDFilePath(String ext) {
        return new FilePathBuilder().year().month().uuid().extension(ext).build();
    }

    /**
     * /25/305/abcd.....3e.ext
     *
     * @return
     */
    public static String buildPartUUIDFilePath(String ext) {
        return new FilePathBuilder().partTime().uuid().extension(ext).build();
    }

    /**
     * /25/305/5353543545.ext
     *
     * @return
     */
    public static String buildPartIDFilePath(String ext) {
        return new FilePathBuilder().partId().id().extension(ext).build();
    }

    /**
     * /25/305/5353543545.ext
     *
     * @return
     */
    public static String buildPartBase32FilePath(String ext) {
        return new FilePathBuilder().partId().base32().extension(ext).build();
    }

    /**
     * /25/305/5353543545.ext
     *
     * @return
     */
    public static String buildPartBase58FilePath(String ext) {
        return new FilePathBuilder().partTime().base58().extension(ext).build();
    }
}
